﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;

namespace Needle.Core.Factory
{

    /// <summary>
    /// Uses the System.ComponentModel.TypeDescriptor to create instances.
    /// </summary>
    public class TypeDescriptorFactory : FactoryBase
    {

        #region private fields...

        private IServiceProvider _serviceProvider;
        private Type[] _signature;

        #endregion

        #region constructors...

        /// <summary>
        /// Initializes a TypeDescriptorFactory to create types 
        /// using the constructor with the given signature and
        /// using the TypeDescriptionProvider provided by the service provider.
        /// </summary>
        public TypeDescriptorFactory(IServiceProvider serviceProvider, Type producedType, IList<Type> signature)
            : base(producedType)
        {
            /* we don't care if the serviceProvider is null, 
             * TypeDescriptor.CreateInstance works ok without one. */
            this._serviceProvider = serviceProvider;

            /* copy signature if it's not empty, 
             * to prevent people changing it after construction.*/
            if (signature != null && signature.Count > 0)
                _signature = signature.ToArray();

        }

        #endregion

        /// <summary>
        /// Creates an instance of concrete type t with the supplied parameters.
        /// </summary>
        public override object CreateInstance(params object[] args)
        {

            return TypeDescriptor.CreateInstance(_serviceProvider, ProducedType, _signature, args);
        }

    }

}
